package org.arclib.time;

public class Time
{

	// / Returns the number of milliseconds since the creation of the
	// application
	public static long getTime()
	{
		return System.currentTimeMillis();
	}

	/**
	 * Calculates fps and captures start of frame time.
	 * 
	 * Call at the start of the frame loop.
	 **/
	public void process()
	{
		if (startOfFrameTime == 0)
		{
			startOfFrameTime = System.currentTimeMillis();
			prevStartOfFrameTime = startOfFrameTime - 1;
		}

		prevStartOfFrameTime = startOfFrameTime;
		startOfFrameTime = System.currentTimeMillis();

		frames++;

		msPassed += (startOfFrameTime - prevStartOfFrameTime);

		if (msPassed > 1000)
		{
			fps_ = frames;
			frames = 0;
			msPassed = 0;
		}
	}

	// / stop execution for some milliseconds
	public void sleep(long milliseconds) throws InterruptedException
	{
		Thread.sleep(milliseconds);
	}

	// / gets the number of milliseconds passed between two calls to process
	public long elapsedMilliseconds()
	{
		return startOfFrameTime - prevStartOfFrameTime;
	}

	// / number of seconds passed between two calls to process
	public double elapsedSeconds()
	{
		return elapsedMilliseconds() / 1000.;
	}

	// / frames per second the application is currently receiving
	public long fps()
	{
		return fps_;
	}

	/**
	 * Call at the end of the frame loop in order to limit the fps to a certain
	 * amount.
	 * 
	 * @throws InterruptedException
	 **/
	public void limitFPS(int maxFps) throws InterruptedException
	{
		// do nothing if max fps less than or equal to zero
		if (maxFps <= 0)
			return;

		int targetMsPerFrame = (int) (1000 / maxFps);
		long cTime = System.currentTimeMillis();

		int sleepAmount = (int) (targetMsPerFrame - (cTime - startOfFrameTime));

		if (sleepAmount <= 0)
			return;

		Thread.sleep(sleepAmount);
	}

	// current time
	long startOfFrameTime = 0;
	// previous time
	long prevStartOfFrameTime = 0;

	long fps_ = 0;

	// helpers for fps calculation
	long frames = 0;
	long msPassed = 0;
}
